import { createContext, useContext, useRef, useState } from "react";
import PropsTest from "./PropsTest";
import CodeBlock from "../../../component/CodeBlock";
import { code } from "./codeData";

const MsgContext = createContext('');

function A() {
    return (
        <>
            组件A
            <B></B>
        </>
    );
}
function B() {
    const msg = useContext(MsgContext);
    return (
        <>
            组件B。
            {msg}
        </>
    );
}


function PropsFather() {
    const propsTestRef = useRef<any>(null);
    const [count, setCount] = useState(0);
    const msg = 'this is a message'
    return (<div className="tab-pane">
        <h1>Props</h1>
        <p>Props（属性）是父组件传递给子组件的数据。Props是只读的，子组件不能修改从父组件接收的props。</p>

        <h3>传递Props</h3>
        <p>可以通过在组件标签上添加属性来传递props。</p>
        <CodeBlock code={code.pro1}></CodeBlock>

        <h3>默认Props</h3>
        <p>可以为组件的props设置默认值，当没有提供props时使用。</p>
        <CodeBlock code={code.pro2}></CodeBlock>

        <h3>Props验证</h3>
        <p>可以使用PropTypes库来验证组件接收的props类型。</p>
        <CodeBlock code={code.pro3}></CodeBlock>

        <h1>数据传递</h1>
        <PropsTest
            ref={propsTestRef}
            count={count}
            changeCount={(newValue: number) => {
                setCount(newValue)
            }}
            msg="来自父组件的初始消息"
        ></PropsTest>
        &nbsp;&nbsp;
        <button onClick={() => setCount(count + 1)} className='mainButton'>父传子</button>
        &nbsp;&nbsp;
        <button onClick={() => {
            if (propsTestRef.current) {
                propsTestRef.current.updateMsg("父组件修改的子组件消息");
            }

        }} className='mainButton'>修改子组件属性或调用子组件方法</button>
        <p>父子组件之间相互传值</p>
        <CodeBlock code={code.pro4}></CodeBlock>
        <h1>跨组件通信</h1>
        <h3>创建顶层上下文对象 MsgContext </h3>
        <MsgContext.Provider value={msg}>
            <A></A>
        </MsgContext.Provider>
        <CodeBlock code={code.pro5}></CodeBlock>
        <h3>使用</h3>
        <CodeBlock code={code.pro6}></CodeBlock>
        <h3>插槽功能</h3>
        <p>在React中，可以使用props.children实现类似Vue的插槽功能，将子元素渲染到组件内部指定位置。</p>
        <CodeBlock code={code.slot1}></CodeBlock>
    </div>
    );
}

export default PropsFather;